package com.ham.mud.state;

import com.ham.mud.ServerConnection;
import com.ham.mud.TargetableService;
import com.ham.mud.characters.player.Player;
import com.ham.mud.commands.*;
import com.ham.mud.commands.skills.Skill;
import com.ham.mud.commands.socials.SocialCommand;
import com.ham.mud.commands.spells.SpellCommand;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by hlucas on Jun 16, 2011 at 12:37:42 PM
 */
public class PlayingState extends ConnectionState {
    int regenTicker = 0;
    
    public static Map<String, PlayerCommand> mappedCommands = new HashMap<String, PlayerCommand>();
    public static List<PlayerCommand> listedCommands = new ArrayList<PlayerCommand>();

    static {
        mappedCommands.put("north",             new MoveCommand(0, 1));
        mappedCommands.put("n",                 new MoveCommand(0, 1));
        mappedCommands.put("northeast",         new MoveCommand(1, 1));
        mappedCommands.put("ne",                new MoveCommand(1, 1));
        mappedCommands.put("east",              new MoveCommand(1, 0));
        mappedCommands.put("e",                 new MoveCommand(1, 0));
        mappedCommands.put("southeast",         new MoveCommand(1, -1));
        mappedCommands.put("se",                new MoveCommand(1, -1));
        mappedCommands.put("south",             new MoveCommand(0, -1));
        mappedCommands.put("s",                 new MoveCommand(0, -1));
        mappedCommands.put("southwest",         new MoveCommand(-1, -1));
        mappedCommands.put("sw",                new MoveCommand(-1, -1));
        mappedCommands.put("west",              new MoveCommand(-1, 0));
        mappedCommands.put("w",                 new MoveCommand(-1, 0));
        mappedCommands.put("northwest",         new MoveCommand(-1, 1));
        mappedCommands.put("nw",                new MoveCommand(-1, 1));
        mappedCommands.put("eq",                new EquipmentCommand());
        mappedCommands.put("eqslots",           new EquipmentSlotsCommand());
        mappedCommands.put("equipmentslots",    new EquipmentSlotsCommand());
        mappedCommands.put("wear",              new EquipCommand());
        mappedCommands.put("seppuku",           new SuicideCommand());
        mappedCommands.put("fight",             new KillCommand());
        mappedCommands.put("c",                 new SpellCommand());
        mappedCommands.put("l",                 new LookCommand());

        listedCommands.add(new BuyCommand());
        listedCommands.add(new ColorCommand());
        listedCommands.add(new CommandsCommand());
        listedCommands.add(new ConsiderCommand());
        listedCommands.add(new DropCommand());
        listedCommands.add(new EditCommand());
        listedCommands.add(new EquipCommand());
        listedCommands.add(new EquipmentCommand());
        listedCommands.add(new EquipmentSlotsCommand());
        listedCommands.add(new ExitsCommand());
        listedCommands.add(new GetCommand());
        listedCommands.add(new GodVoiceCommand());
        listedCommands.add(new GossipCommand());
        listedCommands.add(new InventoryCommand());
        listedCommands.add(new KillCommand());
        listedCommands.add(new ListCommand());
        listedCommands.add(new LookCommand());
        listedCommands.add(new MapCommand());
        listedCommands.add(new QuestCommand());
        listedCommands.add(new QuitCommand());
        listedCommands.add(new RecallCommand());
        listedCommands.add(new ReportCommand());
        listedCommands.add(new RestCommand());
        listedCommands.add(new SayCommand());
        listedCommands.add(new ScoreCommand());
        listedCommands.add(new SellCommand());
        listedCommands.add(new SkillsCommand());
        listedCommands.add(new SocialsCommand());
        listedCommands.add(new SpellCommand());
        listedCommands.add(new SpellsCommand());
        listedCommands.add(new SuicideCommand());
        listedCommands.add(new UnequipCommand());
        listedCommands.add(new WhereCommand());
        listedCommands.add(new WhoCommand());
    }

    public PlayingState(ServerConnection connection) {
        super(connection);
        connection.println("");
    }

    @Override
    public void processInput(String line) {
        if(line == null || line.trim().equals("")) {
            connection.printEnd();
            return;
        }

        String[] split = line.split(" ");
        String[] params = new String[split.length - 1];
        for(int i = 1; i < split.length; i++) {
            params[i-1] = split[i];
        }
        
        line = split[0];

        try {
            PlayerCommand command = mappedCommands.get(line);
            if(command == null) {
                command = (PlayerCommand) TargetableService.findTarget(line, listedCommands);
            }

            if(command == null) {
                command = (Skill) TargetableService.findTarget(line, connection.getPlayer().getSkills());
            }

            if(command == null) {
                String social = TargetableService.findTarget(line, SocialCommand.socials);
                if(social != null) {
                    command = new SocialCommand(social);
                }
            }
            
            if(command == null) {
                whatThe(line);
            } else {
                command.execute(connection, params);
            }
            
        } catch(Throwable t) {
            t.printStackTrace();
            connection.printSolo("Don't do that anymore.");
        }
    }

    private void whatThe(String line) {
        System.out.println("[" + line + "] is not a recognized command.");
        connection.printSolo("What does \"" + line + "\" mean?");
    }

    @Override
    public void tick() {
        regenTicker++;
        if(regenTicker == 30) {
            regenTicker = 0;
            Player player = connection.getPlayer();
            player.regen(connection);
        }
    }
}
